home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Periodicals / develop / develop 9 code / Faceless Background Apps / main.c next >
Encoding:
C/C++ Source or Header  |  1992-01-06  |  8.8 KB  |  235 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2. #
  3. #   Apple Developer Technical Support
  4. #
  5. # SmallDaemon
  6. # A small faceless background-only application
  7. #
  8. #   main.c  -   C Source
  9. #
  10. #   Copyright © 1991 Apple Computer, Inc.
  11. #   All rights reserved.
  12. #
  13. #   Versions:   
  14. #               1.0               09/91       C.K. Haun <TR>
  15. #   
  16. #   Components:
  17. #                           main.c
  18. #                           AppleEvents.c
  19. #
  20. # This is a _very_ simple sample showing a do-nothing 
  21. # System 7.0 faceless background application.  
  22. # The main things to note are....
  23. # 1)  Look at the SIZE resource for the flag settings you'll
  24. #  need to let the Finder™ know that you only want to work
  25. #  in the background.
  26. # 2) Notice that you really do have your own heap and your own
  27. #  event loop.  You can do anything a foreground application
  28. #  can do, send AppleEvents, PPC stuff, anything else you'd
  29. #  like EXCEPT a graphic interface.
  30. # 3)  NOTE that no managers are started up.  You cannot start up
  31. #  Window, Menu, Dialogs, or anything else that 
  32. #  deals with the graphic front end.  Just leave them out.
  33. #  You _can_ start up QuickDraw, if you want to use some QuickDraw
  34. #  functions (like offscreen ports), but you CANNOT actually 
  35. #  do any screen drawing.
  36. #
  37. # Of course, a backgrounder can be launched from the Finder™ 
  38. # with a double-click.  However, if you'd like the backgrounder
  39. # to perform some useful service for your main application, driver,
  40. # DA, or whatever, you will want it running all the time.
  41. #  The BEST way to insure this is to install the backgrounder in the
  42. # StartUp Items folder in the system folder.  This will insure that
  43. # it is always launched, and it will also reduce memory fragmentation
  44. # since it will be installed at startup time.  You can search for it
  45. # when you need it with IPCListPorts (see the PPC toolbox documentation).
  46. # Optionally, you can use the LaunchApplication trap to launch it 
  47. # when you need it, and kill it when you're done.  But this could 
  48. # cause some multiFinder heap fragmentation.
  49. #
  50. # And remember, it's a backgrounder, you can't see it.  To kill it
  51. # use TaskIt or ProcDoggie.
  52. #
  53. # ---------------------------------------------------------------
  54. #   Use this sample as a starting point, and adapt its' routines to 
  55. #   meet the specific needs of your project.  
  56. #
  57. ------------------------------------------------------------------------------*/
  58.  
  59. /* This doesn't do much but wait for a quit event.  But, you can expand it */
  60. /* to suit whatever your needs are for a backgrounder.  */
  61. /* Be sure to look at the SIZE resource for this app to see how the */
  62. /* flags should be set for a background-only task */
  63. #include <memory.h>
  64. #include <appleevents.h>
  65. #include <events.h>
  66. #include <types.h>
  67. #include <gestaltequ.h>
  68. /* variables */
  69. Boolean gQuit = false;
  70. EventRecord gERecord;
  71. Boolean gHasAppleEvents;
  72. unsigned long gMySleep = 50000;  /* long time, long time.  Change this if  */
  73. /* you'd like to do null processing. Just keep in mind that the */
  74. /* user does NOT know that you exist, and if you are eating */
  75. /* up a bunch of time the user will not know why his or her */
  76. /* machine is slowing down. */
  77.  
  78. /* structs */
  79. /* a little struct to install handlers from.  Makes it easier to plug in */
  80. /* new handlers */
  81. struct AEinstalls {
  82.     AEEventClass theClass;
  83.     AEEventID theEvent;
  84.     EventHandlerProcPtr theProc;
  85. };
  86. typedef struct AEinstalls AEinstalls;
  87.  
  88. /* prototypes for this file */
  89. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  90. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  91. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  92. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  93. void DoHighLevel(EventRecord *AERecord);
  94. void InitAEStuff(void);
  95.  
  96. main()
  97. {
  98.     /* We are NOT initializing any managers.  We're in the background, with no */
  99.     /* face, we can't use windows or dialogs or menus.  If you need to talk to the */
  100.     /* user you can post a notification, or launch an application to communicate */
  101.     /* Passing an AppleEvent in the launchapplication trap could do the */
  102.     /* communication for you. */
  103.     
  104.     /* Routine to install Apple event handlers */
  105.     InitAEStuff();
  106.  
  107.     /* no nothing but high level events */
  108.     while (gQuit == false) {
  109.         if (WaitNextEvent(highLevelEventMask, &gERecord, gMySleep, 0)) {
  110.             switch (gERecord.what) {
  111.                 case nullEvent:
  112.                     /* no null processing in this example */
  113.                     break;
  114.                     
  115.                 case kHighLevelEvent:
  116.                     DoHighLevel(&gERecord);
  117.                     break;
  118.             }
  119.         }
  120.     }
  121. }
  122.  
  123. /* Here are the AppleEvent handlers for this background-only task. */
  124. /* Since this is a real live application, it can accept and send any */
  125. /* Apple Events you want to send or receive.  */
  126. /* In this case, the only ones that make any sense in this app are */
  127. /* 'oapp' and 'quit' */
  128.  
  129.  
  130. /* InitAEStuff checks for the availability of the AppleEvent Manager and */
  131. /* installs our event handlers. */
  132. /* if the AEM isn't around, we bail. */
  133. void InitAEStuff(void)
  134. {
  135.     static AEinstalls HandlersToInstall[] =  {
  136.          {
  137.             kCoreEventClass, kAEOpenApplication, AEOpenHandler
  138.         },  {
  139.             kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
  140.         },  {
  141.             kCoreEventClass, kAEQuitApplication, AEQuitHandler
  142.         },  {
  143.             kCoreEventClass, kAEPrintDocuments, AEPrintHandler
  144.         }, 
  145.         /* The above are the four required AppleEvents. */
  146.     };
  147.     
  148.     OSErr aevtErr = noErr;
  149.     long aLong = 0;
  150.     Boolean gHasAppleEvents = false;
  151.     /* Check this machine for AppleEvents.  If they are not here (ie not 7.0)
  152.     *   then we exit */
  153.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  154.     /* The following series of calls installs all our AppleEvent Handlers.
  155.     *   These handlers are added to the application event handler list that 
  156.     *   the AppleEvent manager maintains.  So, whenever an AppleEvent happens
  157.     *   and we call AEProcessEvent, the AppleEvent manager will check our
  158.     *   list of handlers and dispatch to it if there is one.
  159.     */
  160.     if (gHasAppleEvents) {
  161.         register qq;
  162.         for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
  163.             aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
  164.                                             HandlersToInstall[qq].theProc, 0, false);
  165.             if (aevtErr) {
  166.                 /* Of course, you can't tell the user why you died directly, since you have no face.  */
  167.                 /* But, you can post a notification from here to let them know. */
  168.                 ExitToShell();                              /* just fail, baby */
  169.             }
  170.         }
  171.     } else {
  172.         ExitToShell();
  173.     }
  174. }
  175.  
  176. /* end InitAEStuff */
  177.  
  178. void DoHighLevel(EventRecord *AERecord)
  179. {
  180.     /* I'm not doing any error handling here because there's not a lot */
  181.     /* I can do, just pass the errors back. */
  182.     AEProcessAppleEvent(AERecord);
  183.     
  184. }
  185.  
  186. /* end DoHighLevel */
  187.  
  188.  
  189. /* This is the standard Open Application event.   */
  190. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  191. {
  192. #pragma unused (messagein,reply,refIn)
  193.     /* we of course don't do anything here, since we're background only */
  194.     /* But this was a normal launch, so return noErr */
  195.     return(noErr);
  196. }
  197.  
  198. /* end AEOpenHandler */
  199.  
  200. /* Open Doc, opens our documents. */
  201. /* In this case, of course, you are in the background so you should return an error */
  202. /* here since you're not opening a document. */
  203. /* Of course, you _might_ want to open a doc, but you will probably */
  204. /* confuse the user if you do, since they will see no action as the */
  205. /*  result of their clicking on a document icon. */
  206. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  207. {
  208. #pragma unused (reply, refIn,messagein)
  209.     /* we of course don't do anything here, so tell the sender that we  */
  210.     /* didn't handle the event */
  211.     return(errAEEventNotHandled);
  212. }
  213.  
  214. /* same logic for printing */
  215. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  216. {
  217. #pragma unused (reply,refIn,messagein)
  218.     /* we of course don't do anything here */
  219.     return(errAEEventNotHandled);
  220. }
  221.  
  222. /* Standard Quit event handler, to handle a Quit event from the Finder, for example.  */
  223. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life.  */
  224. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  225. {
  226. #pragma unused (messagein,refIn,reply)
  227.     extern Boolean Quit;
  228.     /*  This does _NOT_ quit, you */
  229.     /* should NEVER quit from an AppleEvent handler.  Calling */
  230.     /* ExitToShell here would blow up the Finder™ */
  231.     gQuit = true;
  232.     return(noErr);
  233. }
  234.